package com.mikelouis.test.scala.impatient.chapter4_map_tuples

/**
 * Simply for the sake of pure torture, I've eliminated as many '.' as possible in this exercise. Just awful. Let's just
 * see what the consequences are through this exercise.
 *
 * Created by yuazhu on 4/14/2015.
 */
object Chapter4 extends App {
  // 1
  val wishList: Map[String, Double] = Map(
    "Elephantine Braille Input Device" -> 322000,
    "Microsoft Word 95" -> 10,
    "4TB Ram Drive" -> 32000,
    "Apple" -> 0.60)
  println(wishList)
  println(for ((k, v) <- wishList) yield k -> (v * 0.9))
  println(wishList.mapValues({ v: Double => v * 2}))

  // 2
  {
    val in = new java.util.Scanner(new java.io.File("build.sbt"))
    val wordCounts = collection.mutable.Map[String, Int]() withDefault (_ => 0) // awesome
    while (in.hasNext) wordCounts(in next) += 1 // previous line's "awesome" makes this easy
    println(wordCounts)
  }

  // 3
  {
    val in = new java.util.Scanner(new java.io.File("build.sbt"))
    var wordCounts = Map[String, Int]() withDefault (_ => 0)
    while (in.hasNext) {
      val key = in.next
      val currentCount = wordCounts(key)
      wordCounts = wordCounts - key + (key -> (currentCount + 1))
    }
    println(wordCounts)
  }

  // 4
  {
    val in = new java.util.Scanner(new java.io.File("build.sbt"))
    var wordCounts = collection.immutable.SortedMap[String, Int]() withDefault (_ => 0)
    while (in.hasNext) {
      val key = in.next
      val currentCount = wordCounts(key)
      wordCounts = wordCounts - key + (key -> (currentCount + 1))
    }
    println(wordCounts)
  }

  // 5
  {
    val in = new java.util.Scanner(new java.io.File("build.sbt"))
    val wordCounts = new java.util.TreeMap[String, Int]
    while (in.hasNext) {
      val key = in.next
      // If we omit both the . and () for "in.next()", the compiler sees ambiguity here. Need one of those or a blank line!

      if (!(wordCounts containsKey key)) wordCounts put(key, 0)
      wordCounts put(key, (wordCounts get key) + 1) // Just awful, parens (or dots) required, or else order of ops will cause wrong behavior.
    }
    println(wordCounts)
  }

  // 6

  import java.util.Calendar._

  val stringsToCalConst = collection.mutable.LinkedHashMap(
    "Monday" -> MONDAY,
    "Tuesday" -> TUESDAY,
    "Wednesday" -> WEDNESDAY,
    "Thursday" -> THURSDAY,
    "Friday" -> FRIDAY,
    "Saturday" -> SATURDAY,
    "Sunday" -> SUNDAY)
  println(stringsToCalConst)

  // 7
  val props = collection.JavaConversions propertiesAsScalaMap (System getProperties)
  val maxLengthKey = ((props keySet) toList) maxBy (_ size) // '.' would make this a lot easier. Many extra parens are necessary.
  for ((k, v) <- props) {
    println(k + " " * ((maxLengthKey size) - (k size)) + " | " + v) // This makes a good case why being pro-whitespace can be dead wrong.
  }

  // 8
  val arr = Array(-5, 0, 5, 9, -2, 17, 3)

  def minmax(values: Array[Int]) = {
    (values.min, values.max)
  }

  println(minmax(arr))

  // 9
  def lteqgt(values: Array[Int], v: Int) = {
    (values.count(_ < v), values.count(_ == v), values.count(_ > v)) // All except tuple's parentheses could be eliminated with '.'
  }

  println(lteqgt(arr, 0))

  // 10
  /* Returns a string formed from this string and another iterable collection by combining corresponding elements in pairs. If one of the two collections is longer than the other, its remaining elements are ignored */
  println("Hello".zip("World"))
  // Encryption?

  // Allowing so many '.' to be omitted can easily become detrimental as above. If it is to be, it is up to me... D.A.R.E
}
